home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CD ROM Paradise Collection 4
/
CD ROM Paradise Collection 4 1995 Nov.iso
/
program
/
hgc32_12.zip
/
HGC32.C
< prev
next >
Wrap
C/C++ Source or Header
|
1995-01-29
|
11KB
|
381 lines
/*+--------------------------------------------------------------+*/
/*| |*/
/*| Source code for TDVIDEO.DLL (for TD32.EXE) |*/
/*| for debugging 32-bit DOS programs (DPMI32) on systems |*/
/*| with single monochrome monitor driven by Hercules |*/
/*| graphics card. |*/
/*| |*/
/*| version 1.2 (c) 29.01.1995 Wojciech M. Zabolotny |*/
/*| (WZAB@ipe.pw.edu.pl) |*/
/*| |*/
/*| This source is based on Help file for Borland's |*/
/*| TDWINI.EXE (structure of TDVIDEO.DLL library) |*/
/*| |*/
/*| Many thanks to all the people who helped me to discover |*/
/*| how to detect graphics modes of HGC card. |*/
/*| |*/
/*+--------------------------------------------------------------+*/
#include <windows.h>
#include <dos.h>
#include <stdio.h>
#include <conio.h>
/* Definitions of Hercules card's registers */
#define HGC_Index 0x3b4
#define HGC_Data 0x3b5
#define HGC_Mode 0x3b8
#define HGC_LightPenSet 0x3b9
#define HGC_LightPenReset 0x3bb
#define HGC_Status 0x3ba
#define HGC_Config 0x3bf
#define HGC_LightPenExt 0x3bf
WORD selB000 = 0; /* selector of HGC's screen memory */
WORD sel0040 = 0; /* selector of BIOS data segment */
/*====================================================================*/
/* Block of functions and variables used to save and restore BIOS */
/* state (size and location of cursor). */
/*====================================================================*/
unsigned char cRow,cCol,cStart,cEnd;
void SaveBiosCursor(void)
{
asm {
mov ah,0x03
mov bh,0
int 0x10
mov cRow,dh
mov cCol,dl
mov cStart,ch
mov cEnd,cl
}
}
void RestoreBiosCursor(void)
{
asm {
mov ah,01
mov ch,cStart
mov cl,cEnd
int 0x10 /* Size of cursor restored */
mov ah,02
mov bh,0
mov dh,cRow
mov dl,cCol
int 0x10 /* Location of cursor restored */
}
}
/* This function sets BIOS flag at 0x40:0x65 to the last value */
/* written to HGC's display's mode register */
void SetVMode (unsigned char vmode)
{
asm {
push es
mov ax,sel0040
mov es,ax
mov al,vmode
mov [byte ptr ES:0x65],al
pop es
}
return;
}
/*====================================================================*/
/* Block of functions and variables used to save and restore video */
/* memory */
/*====================================================================*/
/* Buffer for user's program video memory contents */
unsigned char OldVMem[0x1000]; /* 4kB */
void RestoreVideoMemory(void)
{
/* This function restores previous video memory contents, saved */
/* by SaveVideoMemory function */
asm {
push es
push ds
push esi
push edi
mov ax,selB000
mov es,ax
xor edi,edi
lea esi,OldVMem
cld
mov ecx,1024 /* 4kB/4 */
rep movsd
pop edi
pop esi
pop ds
pop es
}
}
void SaveVideoMemory(void)
/* Save previous video memory contents */
{
asm {
push es
push ds
push esi
push edi
mov ax,ds
mov es,ax
lea edi,[OldVMem]
mov ax,selB000
mov ds,ax
xor esi,esi
cld
mov ecx,1024 /* 4kB/4 */
rep movsd
pop edi
pop esi
pop ds
pop es
}
}
/*====================================================================*/
/* Block of functions and variables used to save and restore state of */
/* Hercules graphics card */
/*====================================================================*/
unsigned char HGCPage; /* Number of visible graphics page */
unsigned char HGCGraph; /* 0 in text mode, 1 in graphics mode */
void GetHGCMode(void)
{
unsigned char LpExt;
unsigned short int CharNum;
asm {
mov dx,HGC_Status
}
/* Wait one frame before mode detection. If detection is performed */
/* immediately (as it was in version 1.0), wrong mode can be */
/* detected when breakpoint is set near after "closegraph" or */
/* "restorecrtmode" function call. */
wait_novsync:
asm {
in al,dx
and al,0x80
je wait_novsync /* If VSYNC pulse has already begun, wait */
/* until it finishes */
}
wait_vsync:
asm {
in al,dx
and al,0x80
jne wait_vsync: /* Wait for the beginning of VSYNC pulse */
}
/* Frame completed, detect graphics mode */
wait_novsync2:
asm {
in al,dx
and al,0x80
je wait_novsync2 /* If VSYNC pulse has already begun, wait */
/* until it finishes */
}
wait_vsync2:
asm {
in al,dx
and al,0x80
jne wait_vsync2: /* Wait for the beginning of VSYNC pulse */
/* Use light pen's trigger to obtain number of character */
/* displayed at the beginning of VSYNC pulse, and infor- */
/* mation about the visible graphics page */
mov dx,HGC_LightPenReset
out dx,al
mov dx,HGC_LightPenSet
out dx,al
mov dx,HGC_LightPenExt
in al,dx
mov LpExt,al
mov dx,HGC_Index
mov al,16
out dx,al
mov dx,HGC_Data
in al,dx
mov ah,al
mov dx,HGC_Index
mov al,17
out dx,al
mov dx,HGC_Data
in al,dx
mov CharNum,ax
}
/* If the number of character displayed at the beginning of VSYNC */
/* pulse is greater then 0xc000 then it is graphics mode */
HGCGraph = (CharNum >= 0xc00) ? 1 : 0;
/* Number of graphics page is available as bit 7 of Light Pen Exten- */
/* sion register */
HGCPage = (LpExt & 0x80) ? 1 : 0;
}
void SetHGCMode(unsigned char GraphFlag,unsigned char Page)
/* If GraphFlag != 0 this function switches graphics mode on and sets */
/* visible page according to Page parameter. If GraphFlag == 0, this */
/* function switches on the text mode. */
{
int i,mode;
unsigned char vmode;
static unsigned char CRTC[2][12] ={
{0x61,0x50,0x52,0x0f,0x19,0x06,0x19,0x19,0x02,0x0d,0x0b,0x0c},
{0x35,0x2d,0x2e,0x07,0x5b,0x02,0x57,0x57,0x02,0x03,0x00,0x00 }
};
if(GraphFlag) {
mode=1;
outportb( HGC_Config, 3 );
if(Page==1) vmode=0x8a;
else vmode=0x0a;
}
else {
mode=0;
outportb( HGC_Config, 0 );
vmode=0x29;
}
outportb( HGC_Mode, vmode );
for ( i=0; i < 12; i++ ) {
outportb( HGC_Index, i );
outportb( HGC_Data, CRTC[mode][i] );
};
SetVMode(vmode);
};
/*====================================================================*/
/* Block of functions required for DLL library */
/*====================================================================*/
/*--------------------------------------------------------------------------*/
#pragma argsused
int FAR PASCAL LibMain( HANDLE h, WORD wDataSegment,
WORD wHeapSize, LPSTR lpszCmdLine )
{
return 1; /* Return success */
}
/*--------------------------------------------------------------------------*/
#pragma argsused
int FAR PASCAL WEP ( int bSystemExit )
{
return 1; /* Return success */
}
/*====================================================================*/
/* Block of functions required for TDVIDEO.DLL library */
/*====================================================================*/
/*--------------------------------------------------------------------------*/
WORD FAR PASCAL _export VideoInit (void)
{
asm {
mov ax,2
mov bx,0x0040
int 0x31
jc Error
mov sel0040,ax
mov ax,2
mov bx,0xB000
int 0x31
jc Error
mov selB000,ax
}
printf("TDVIDEO.DLL for HGC v1.2 (c) 29.01.1995 W.M. Zabolotny\n");
return 0; /* Return success */
Error:
return 5; /* Error - it was imposible to obtain one of selectors */
}
/*--------------------------------------------------------------------------*/
WORD FAR PASCAL _export VideoDone (void)
{
SetHGCMode(0,0);
clrscr();
return 1; /* Return success */
}
/*--------------------------------------------------------------------------*/
WORD FAR PASCAL _export VideoIsColor (void)
{
return 0; /* Always mono monitor */
}
/*--------------------------------------------------------------------------*/
#pragma argsused
WORD FAR PASCAL _export VideoGetTextSelector (int display)
{
return selB000; /* Always mono monitor */
}
/*--------------------------------------------------------------------------*/
void FAR PASCAL _export VideoSetCursor (WORD y, WORD x)
{
asm {
mov ah,2
mov bh,0
mov dh,byte ptr y
mov dl,byte ptr x
int 0x10
/* Cursor moved to the location pointed by x and y */
}
}
/*--------------------------------------------------------------------------*/
void FAR PASCAL _export VideoDebuggerScreen (void)
{
/* Save debugged program's screen */
GetHGCMode(); /* Save the previous video mode */
SaveVideoMemory();
SaveBiosCursor();
SetVMode(0x29);
SetHGCMode(0,0);
}
/*--------------------------------------------------------------------------*/
void FAR PASCAL _export VideoWindowsScreen (void)
{
/* Restore debugged program's screen */
SetHGCMode(HGCGraph,HGCPage);
RestoreVideoMemory();
RestoreBiosCursor();
}
/*--------------------------------------------------------------------------*/
WORD FAR PASCAL _export VideoBigSize (void)
{
/* Screen height is always 25 lines. */
return 25;
}
/*--------------------------------------------------------------------------*/
#pragma argsused
WORD FAR PASCAL _export VideoSetUp (WORD xtra1, WORD xtra2)
{
/* This function does nothing */
return 0;
}
/*--------------------------------------------------------------------------*/
#pragma argsused
void FAR PASCAL _export VideoSetSize (WORD bigflag)
{
/* Do nothing, screen size is never to be changed. */
}
/*--------------------------------------------------------------------------*/
#pragma argsused
void FAR PASCAL _export VideoUpdateWindow (void)
{
/* Do nothing, Turbo Debugger displays all necessary information by itself. */
}
/*--------------------------------------------------------------------------*/
#pragma argsused
void FAR PASCAL _export VideoConfig (HWND hWnd, HINSTANCE hInst, char *HelpFile)
{
/* Function not implemented, because HGC32.DLL can't work with TDWINI.EXE. */
}